package com.zbkj.crmeb.chant.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.crmeb.core.exception.CrmebException;
import com.utils.CrmebUtil;
import com.zbkj.crmeb.category.model.CategoryUpdateLog;
import com.zbkj.crmeb.category.service.CategoryUpdateLogService;
import com.zbkj.crmeb.enums.CategoryTypeEnum;
import com.zbkj.crmeb.store.model.StoreProduct;
import com.zbkj.crmeb.store.service.StoreProductService;
import com.zbkj.crmeb.system.service.SystemAttachmentService;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.CommonPage;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zbkj.crmeb.chant.dao.CategoryMatchMapper;
import com.zbkj.crmeb.chant.dto.CategoryMatchDTO;
import com.zbkj.crmeb.chant.model.CategoryMatch;
import com.zbkj.crmeb.chant.service.ICategoryMatchService;
import com.zbkj.crmeb.chant.vo.CategoryMatchRequest;

import cn.hutool.core.bean.BeanUtil;

@Service
public class CategoryMatchServiceImpl extends ServiceImpl<CategoryMatchMapper, CategoryMatch> implements ICategoryMatchService, ApplicationRunner {
    @Autowired
    CategoryMatchMapper mapper;

    @Autowired
    private SystemAttachmentService systemAttachmentService;

    @Autowired
    StoreProductService storeProductService;
    @Autowired
    private CategoryUpdateLogService categoryUpdateLogService;

    /**
     * 分页查询
     */
    @Override
    public PageInfo<CategoryMatch> pageEntity(CategoryMatchRequest request) {
        Page<Object> page = PageHelper.startPage(request.getPageNow(), request.getPageSize());
        List<CategoryMatch> storeBrand = this.list(Wrappers.<CategoryMatch>lambdaQuery()
                .eq(null != request.getType(), CategoryMatch :: getType, request.getType())
                .eq(null != request.getOthCategoryName(), CategoryMatch :: getOthCategoryName, request.getOthCategoryName())
                );

        return CommonPage.copyPageInfo(page, storeBrand);
    }

    /**
     * 主键查询
     */
    @Override
    public CategoryMatch getEntity(Integer id) {
        CategoryMatch storeBrand = this.getById(id);

        return storeBrand;
    }

    /**
     * 保存
     */
    @Override
    public Boolean saveEntity(CategoryMatchDTO dto) {
        CategoryMatch storeBrand = new CategoryMatch();
        BeanUtil.copyProperties(dto, storeBrand,"type");
        storeBrand.setType(CategoryTypeEnum.valueOf(dto.getType()));
        if( 1 == dto.getType()){
//            checkField(dto);
            if( checkName(dto) > 0){
                throw new CrmebException("当前分类下此分类名称已存在");
            }
            storeBrand.setPath(getPathByPId(storeBrand.getPid()));
            storeBrand.setExtra(systemAttachmentService.clearPrefix(storeBrand.getExtra()));
        }
        storeBrand.setCreateTime(new Date());
        storeBrand.setUpdateTime(new Date());

        mapper.insert(storeBrand);
        CategoryUpdateLog categoryUpdateLog = new CategoryUpdateLog();
        categoryUpdateLog.setCategoryId(storeBrand.getId());
        categoryUpdateLog.setImage(storeBrand.getExtra());
        categoryUpdateLogService.save(categoryUpdateLog);
        return true;
    }

    /**
     * 修改
     */
    @Override
    public Boolean updateEntity(CategoryMatchDTO dto) {
        CategoryMatch storeBrand = new CategoryMatch();
        BeanUtil.copyProperties(dto, storeBrand,"type");
        storeBrand.setType(CategoryTypeEnum.valueOf(dto.getType()));
        storeBrand.setUpdateTime(new Date());
        if(1 == dto.getType()){
            if( checkName(dto) > 0){
                throw new CrmebException("当前分类下此分类名称已存在");
            }
//            checkField(dto);
            storeBrand.setPath(getPathByPId(storeBrand.getPid()));
            storeBrand.setExtra(systemAttachmentService.clearPrefix(storeBrand.getExtra()));
        }
        mapper.updateById(storeBrand);
        if(1 == dto.getType()){
            //如状态为关闭，那么所以子集的状态都关闭
            if(!dto.getStatus()){
                updateStatusByPid(dto.getId(), false);
            }else{
                //如是开启，则父类的状态为开启
                updatePidStatusById(dto.getId());
            }
        }
        CategoryUpdateLog categoryUpdateLog = new CategoryUpdateLog();
        categoryUpdateLog.setCategoryId(storeBrand.getId());
        categoryUpdateLog.setImage(storeBrand.getExtra());
        categoryUpdateLogService.save(categoryUpdateLog);
        return true;
    }

    @Override
    public Object del(Integer id) {
        //查看是否有子类
        QueryWrapper<CategoryMatch> queryWrapper = new QueryWrapper<>();
//        objectQueryWrapper.eq("status", 1);
        queryWrapper.like("path", "/"+id+"/");
        if(count(queryWrapper) > 0){
            throw new CrmebException("当前分类下有子类，请先删除子类！");
        }
        //查询该分类是否有商品
        int count = storeProductService.count(Wrappers.lambdaQuery(StoreProduct.class).eq(StoreProduct::getIsDel, 0).eq(StoreProduct::getCateId, id));
        if(count>0){
            throw new CrmebException("该分类下有商品");
        }
        return removeById(id);
    }

    /**
     * 修改分类以及子类的状态
     * @param pid
     * @param status
     * @return
     */
    private boolean updateStatusByPid(Integer pid, boolean status) {
        //查看是否有子类
        CategoryMatch categoryMatch= new CategoryMatch();
        categoryMatch.setStatus(status);
        QueryWrapper<CategoryMatch> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.like("path", "/"+pid+"/");
        return update(categoryMatch, objectQueryWrapper);
    }

    /**
     * 获取分类下子类
     * @param id
     * @return
     */
    @Override
    public List<CategoryMatch> getChildVoListByPid(Integer id) {
        //查看是否有子类
        QueryWrapper<CategoryMatch> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.eq("status", 1);
        objectQueryWrapper.like("path", "/"+id+"/");
        return mapper.selectList(objectQueryWrapper);
    }

    /**
     * 获取分类下三级子类
     * @param id
     * @return
     */
    @Override
    public List<CategoryMatch> getThreeChildVoListByPid(Integer id) {
        List<CategoryMatch> cateList = new ArrayList<>();
        // 查询当前分类
        CategoryMatch categoryMatch = getById(id);
        if(null == categoryMatch){
            return cateList;
        }
        //判断是否为三级分类
        if(Arrays.asList(categoryMatch.getPath().split("/")).size() == 4){
            cateList.add(categoryMatch);
        }else {
            List<CategoryMatch> list = getChildVoListByPid(id);
            if(categoryMatch.getPid() != 0){
                return list;
            }
            //当前二级分类
            for (CategoryMatch cate : list) {
                cateList.addAll(getChildVoListByPid(cate.getId()));
            }
        }
        return cateList;
    }

    /**
     * 查询商户已启用的分类
     * @param
     * @return java.util.List<com.zbkj.crmeb.chant.model.CategoryMatch>
     */
    @Override
    public List<CategoryMatch> getCategoryMatch(Integer merId, Integer... cateId) {
        return mapper.getCategoryMatch(merId, cateId);
    }
    
    /**
     * 查询商户已启用的分类(只返回id)
     * @param
     * @return java.util.List<com.zbkj.crmeb.chant.model.CategoryMatch>
     */
    @Override
    public List<Integer> getCategoryMatchIds(Integer merId) {
    	return mapper.getCategoryMatchIds(merId);
    }
    
    /**
     * 获取商户不可见分类(包括总分类和商户分类)
     */
    @Override
    public List<CategoryMatch> selectCategoryMatchDisable(Integer merId) {
    	return mapper.selectCategoryMatchDisable(merId);
    }

    @Override
    public Map<Integer, String> getTripletCateName(List<Integer> cateIds) {
        Map<Integer, String> map = new HashMap<>();
        if(CollectionUtils.isEmpty(cateIds)){
            return map;
        }
        List<CategoryMatch> list =mapper.getTripletCateName(cateIds);
        map = list.stream().collect(Collectors.toMap(CategoryMatch::getId, CategoryMatch::getName));
        return map;
    }

    /**
     * 通过id集合获得列表
     * @param cateIdList
     * @return
     */
    @Override
    public List<CategoryMatch> getByIds(List<Integer> cateIdList) {
        LambdaQueryWrapper<CategoryMatch> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(CategoryMatch::getId, cateIdList);
        return mapper.selectList(lambdaQueryWrapper);
    }

    /**
     * 开启父级状态
     * @param id Integer
     * @author Mr.Zhang
     * @since 2020-04-16
     */
    private void updatePidStatusById(Integer id) {
        CategoryMatch categoryMatch = getById(id);
        List<Integer> categoryIdList = CrmebUtil.stringToArrayByRegex(categoryMatch.getPath(), "/");
        categoryIdList.removeIf(i -> i.equals(0));
        ArrayList<CategoryMatch> categoryArrayList = new ArrayList<>();
        if(categoryIdList.size() < 1){
            return;
        }
        for (Integer categoryId: categoryIdList) {
            CategoryMatch categoryVo = new CategoryMatch();
            categoryVo.setId(categoryId);
            categoryVo.setStatus(true);
            categoryArrayList.add(categoryVo);
        }
        updateBatchById(categoryArrayList);
    }

    public void checkField(CategoryMatchDTO dto){
        if(null == dto.getPid()){
            throw new CrmebException("请选择父级分类");
        }
        if(StringUtils.isNotBlank(dto.getName())){
            throw new CrmebException("分类名称必须填写");
        }
        if(null ==  dto.getStatus()){
            throw new CrmebException("状态必须选择");
        }
        if(null == dto.getSort()){
            throw new CrmebException("排序数字不能为空");
        }else {
            if(dto.getSort() < 0){
                throw new CrmebException("排序数字必须大于等于0");
            }
        }
    }

    public String getPathByPId(Integer pid) {
        if(0 == pid){
            return "/0/";
        }
        CategoryMatch categoryMatch = getById(pid);
        if(null != categoryMatch){
            String path = categoryMatch.getPath();
            if(Arrays.asList(path.split("/")).size() >= 4){
                throw new CrmebException("三级分类不可以再添加子类目");
            }
            return categoryMatch.getPath() + pid + "/";
        }
        return null;
    }

    public int checkName(CategoryMatchDTO dto) {
        if(null == dto.getPid()){
            throw new CrmebException("pid不能为空");
        }
        LambdaQueryWrapper<CategoryMatch> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(CategoryMatch::getName, dto.getName())
                .eq(CategoryMatch::getType, dto.getType())
                .eq(CategoryMatch::getPid,dto.getPid())
                .ne(!Objects.isNull(dto.getId()),CategoryMatch::getId,dto.getId());
        return count(lambdaQueryWrapper);
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
//        initCategory();
    }

    private void initCategory(){
        try {
            FileInputStream fis = new FileInputStream(new File("D:\\bieyang\\easy(1).xlsx")); //替换为你的Excel文件路径
            //创建一个工作簿
            Workbook workbook = new XSSFWorkbook(fis);
            //获取第一个工作表
            Sheet sheet = workbook.getSheetAt(0);
            int index = 0;
            for (Row cells : sheet) {
                index++;
                if (index == 1){
                    continue;
                }
                if (null==cells.getCell(0)){
                    continue;
                }

                String othCategory = cells.getCell(0).getStringCellValue();
                othCategory = othCategory.replace(" ","");
//                String categoryId = "";
//                if (cells.getCell(1)!=null){
//                    categoryId = cells.getCell(1).getStringCellValue();
//                }
                String othCategoryId = cells.getCell(1).getStringCellValue();
                int categoryId = 0;
                if (cells.getCell(3)!=null){
                    categoryId = (int) cells.getCell(3).getNumericCellValue();
                }
                if (StringUtils.isBlank(othCategory) || categoryId == 0){
                    continue;
                }
                System.out.println(othCategory+"--"+categoryId);
                CategoryMatch categoryMatch = new CategoryMatch();
                categoryMatch.setCategoryId(categoryId);
                categoryMatch.setType(CategoryTypeEnum.EASY);
                categoryMatch.setStatus(true);
                categoryMatch.setSort(0);
                categoryMatch.setIsAdvice(0);
                categoryMatch.setOthCategoryName(othCategory);
                categoryMatch.setOthCategoryId(othCategoryId);
                categoryMatch.setCreateTime(new Date());
                categoryMatch.setUpdateTime(new Date());
                categoryMatch.setWeight(BigDecimal.ZERO);
                categoryMatch.setItFirst(BigDecimal.ZERO);
                categoryMatch.setHkFirst(BigDecimal.ZERO);
                this.save(categoryMatch);

            }

            workbook.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
